package com.freestyle.seatabusiness.authorization.service;

import com.freestyle.easyshiro.SessionUtils;
import com.freestyle.easyshiro.intercept.method.SessionTokenUtils;
import com.freestyle.easyshiro.realms.UsernamePasswordTokenEx;
import com.freestyle.jwt.JwtUtils;
import com.freestyle.seatabusiness.api.service.AuthorizationService;
import com.freestyle.seatabusiness.authorization.config.AuthenConfig;
import com.freestyle.sentinel.SentinelResponseEntity;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.ExpiredSessionException;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.subject.Subject;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * Created by rocklee on 2022/4/6 9:51
 */
@DubboService(cluster = "failover")//默认重试两次
public class AuthorizationServiceImp implements AuthorizationService {
  @Resource
  private AuthenConfig authenConfig;
  @Resource
  private SessionUtils sessionUtils;
  @Override
  public SentinelResponseEntity login(String user, String password,String ... sessionId) {
    if (user==null){
      return SentinelResponseEntity.fromResult(0,"显示登录界面");
    }
    SessionTokenUtils.updateSecurityManager();
    SentinelResponseEntity<String> entity=new SentinelResponseEntity<>();
    Subject subject =null;
    try {
      subject= sessionId.length > 0 && !StringUtils.isBlank(sessionId[0]) ?
              sessionUtils.createSubject(sessionId[0]) : SecurityUtils.getSubject(); // 获取当前主体
    }
    catch (ExpiredSessionException| UnknownSessionException e){
      subject=SecurityUtils.getSubject();
    }
    UsernamePasswordToken token = new UsernamePasswordTokenEx(user, password,"business-app");
    try {
      subject.login(token); // 登录
      if (!StringUtils.isBlank(authenConfig.getProperties().getSessionTokenName())){
        entity.put(authenConfig.getProperties().getSessionTokenName(), subject.getSession().getId().toString());
      }
      if (!StringUtils.isBlank(authenConfig.getProperties().getJwtTokenName())){
        String jwtToken= JwtUtils.getToken(subject.getSession().getId(),authenConfig.getProperties().getSessionTimeOut(), TimeUnit.SECONDS);
        //返回两组token，之后的访问随便用哪个
        entity.put(authenConfig.getProperties().getJwtTokenName(), jwtToken);
      }
      entity.setResult("OK");
      return entity;
    }
    catch (UnknownAccountException | IncorrectCredentialsException e){
      return SentinelResponseEntity.fromErr(0,1,"用户或密码无效");
    }
  }
}
